package com.ternnetwork.core.accesscontroll.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.Predicate;

import com.ternnetwork.core.accesscontroll.repository.UserRoleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.ternnetwork.commons.model.http.BaseResponse;
import com.ternnetwork.core.accesscontroll.dto.RoleQueryDto;
import com.ternnetwork.core.accesscontroll.entity.Role;
import com.ternnetwork.core.accesscontroll.enums.messages.RoleMessages;
import com.ternnetwork.core.accesscontroll.repository.RescRoleRepository;
import com.ternnetwork.core.accesscontroll.repository.RoleRepository;
import com.ternnetwork.core.accesscontroll.service.RoleService;



@Service
public class RoleServiceImpl implements RoleService {
	
	@Autowired
	private RoleRepository roleRepository;
	
	@Autowired
	private RescRoleRepository rescRoleRepository;

	@Autowired
	private UserRoleRepository userRoleRepository;
	
	@Override
	public BaseResponse getOne(Long id) {
		
		BaseResponse  baseResponse=new BaseResponse();
		
		Role t=roleRepository.getOne(id);
		
		baseResponse.setSccucess(t);
		
		return baseResponse;
	}
	@Override
    public BaseResponse add(Role t) {
    	
    	BaseResponse  baseResponse=checkProperties(t);
    	
    	if(baseResponse.getStatus().intValue()==0) {
    		return baseResponse;
    	}
    	
    	long totalCount=roleRepository.getCountByCode(t.getNameEn());
    	
      	if(totalCount>0L) {
    		baseResponse.setFailed(RoleMessages.FAILED_MESSAGE_CODE_CAN_NOT_BE_DUPLICATE.getName());
    		return baseResponse;
    	}
      	
    	t.setNameEn(t.getNameEn().toUpperCase());
    	
    	roleRepository.saveAndFlush(t);
		
		baseResponse.setSccucess(t);
		
		return baseResponse;
	}
    
    
	@Override
    public BaseResponse update(Role t) {
   	 
        BaseResponse  baseResponse=checkProperties(t);
    	//校验不通过
    	if(baseResponse.getStatus().intValue()==0) {
    		return baseResponse;
    	}
    	
    	long totalCount=roleRepository.getCountByCodeAndExcludeId(t.getNameEn().toUpperCase(), t.getId()); 
    	
      	if(totalCount>0L) {
    		baseResponse.setFailed(RoleMessages.FAILED_MESSAGE_CODE_CAN_NOT_BE_DUPLICATE.getName());
    		return baseResponse;
    	}
    	
      	Role old=roleRepository.getOne(t.getId());
    	
    	if(old==null||old.getId().longValue()==0L) {
    		baseResponse.setFailedForObjectNotExist();
    		return baseResponse;
    	}
    	
    	old.setCategory(t.getCategory());
    	old.setDescription(t.getDescription());
    	old.setNameEn(t.getNameEn().toUpperCase());
    	old.setNameZh(t.getNameZh());
    	
     	roleRepository.saveAndFlush(old);
		baseResponse.setSccucess(t);
		return baseResponse;
	}
	@Override
    public BaseResponse findByPage(Pageable pageable,RoleQueryDto dto) {
    	  
    	 BaseResponse  baseResponse=new BaseResponse();
    	
     	 Page<Role> page = roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {

         List<Predicate> predicates = new ArrayList<>();

         if(!StringUtils.isEmpty(dto.getNameEn())){
             predicates.add(criteriaBuilder.like(root.get("nameEn").as(String.class),"%".concat(dto.getNameEn().toUpperCase()).concat("%")));
         }
         
         if(!StringUtils.isEmpty(dto.getNameZh())){
             predicates.add(criteriaBuilder.like(root.get("nameZh").as(String.class),"%".concat(dto.getNameZh().toUpperCase()).concat("%")));
         }

         Predicate[] predicateArray = new Predicate[predicates.size()];

         return criteriaBuilder.and(predicates.toArray(predicateArray));
     }, pageable);
     	 
     	baseResponse.setSccucess(page);
    	
    	return baseResponse;
    }
    
	@Override
	public BaseResponse findAll(RoleQueryDto dto) {
		   
   	    BaseResponse  baseResponse=new BaseResponse();
   	
    	List<Role> itemList = roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {

        List<Predicate> predicates = new ArrayList<>();

        if(!StringUtils.isEmpty(dto.getNameEn())){
            predicates.add(criteriaBuilder.like(root.get("nameEn").as(String.class),"%".concat(dto.getNameEn().toUpperCase()).concat("%")));
        }
        
        if(!StringUtils.isEmpty(dto.getNameZh())){
            predicates.add(criteriaBuilder.like(root.get("nameZh").as(String.class),"%".concat(dto.getNameZh().toUpperCase()).concat("%")));
        }
        Predicate[] predicateArray = new Predicate[predicates.size()];

        return criteriaBuilder.and(predicates.toArray(predicateArray));
    });
   	 
    	baseResponse.setSccucess(itemList);
   	
   	    return baseResponse;
	}
    
    
    
	@Override
	@Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor=Exception.class)
    public BaseResponse deleteById(Long id) {
		
		BaseResponse  baseResponse=new BaseResponse();
		
		Role old=roleRepository.getOne(id);
		
		if(old==null||old.getId().longValue()==0L) {
    		baseResponse.setFailedForObjectNotExist();
    		return baseResponse;
    	}
		
		if(old.getId().longValue()==1L) {
			baseResponse.setFailed(RoleMessages.FAILED_MESSAGE_OBJECT_CAN_NOT_BE_DELETED.getName());
    		return baseResponse;
		}
		userRoleRepository.deleteAllByRoleId(id);

		rescRoleRepository.deleteAllByRoleId(id);
		
		roleRepository.delete(old);
		
		baseResponse.setSccucess();
		
		return baseResponse;
	}
	
  
	@Override
	public BaseResponse findAllByCategory(String category) {
		
		BaseResponse  baseResponse=new BaseResponse();
		
		List<Role> t=roleRepository.findAllByCategory(category);
		
		baseResponse.setSccucess(t);
		
		return baseResponse;
	}
	
	@Override
	public BaseResponse findAll() {
		
		BaseResponse  baseResponse=new BaseResponse();
		
		List<Role> t=roleRepository.findAll();
		
		baseResponse.setSccucess(t);
		
		return baseResponse;
	}
	@Override
   public BaseResponse findByCode(String code) {
		
		BaseResponse  baseResponse=new BaseResponse();
		
		List<Role> t=roleRepository.findByCode(code);
		
		baseResponse.setSccucess(t);
		
		return baseResponse;
	}
   
   
   /**
    * 检查属性
    * @param t
    * @return
    */
   private BaseResponse checkProperties (Role t) {
  	 
		BaseResponse  baseResponse=new BaseResponse();
		    
	    if(StringUtils.isEmpty(t.getNameEn())) {
	    	baseResponse.setFailed(RoleMessages.FAILED_MESSAGE_CODE_CAN_NOT_BE_EMPTY.getName());
	    	return baseResponse;
	    }
	
	    if(StringUtils.isEmpty(t.getNameZh())) {
	    	baseResponse.setFailed(RoleMessages.FAILED_MESSAGE_NAME_ZH_CAN_NOT_BE_EMPTY.getName());
	    	return baseResponse;
	    }
	    baseResponse.setSccucess();
	    return baseResponse;
   }

	

}
